﻿using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace HECore.Common.Extensions
{
    /// <summary>
    /// EF IQueryable扩展
    /// </summary>
    public static class IQueryableExtension
    {
        /// <summary>
        /// 分页扩展
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static async Task<PagingResultDto<T>> PagingAsync<T>(this IQueryable<T> query, PagingInput input)
        {
            var Total = await query.CountAsync();
            var skip = (input.Page - 1) * input.Size;
            var items = await query.Skip(skip).Take(input.Size).ToListAsync();
            return new PagingResultDto<T>() { Items = items, Total = Total };
        }

        /// <summary>
        /// 条件扩展
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="condition"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> predicate)
        {
            return condition ? query.Where(predicate) : query;
        }

        /// <summary>
        /// 条件扩展
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="condition"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, int, bool>> predicate)
        {
            return condition ? query.Where(predicate) : query;
        }

        /// <summary>
        /// 条件扩展
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="condition"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> query, bool condition, Func<T, bool> predicate)
        {
            return condition ? query.Where(predicate) : query;
        }
    }

    /// <summary>
    /// 分页结果
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class PagingResultDto<T>
    {
        /// <summary>
        /// 所有数据的总数
        /// </summary>
        public int Total { get; set; }

        /// <summary>
        /// 当前分页数据
        /// </summary>
        public IEnumerable<T> Items { get; set; }
    }

    /// <summary>
    /// 分页参数
    /// </summary>
    public class PagingInput
    {
        /// <summary>
        /// 当前页码
        /// </summary>
        [Required]
        public int Page { get; set; }

        /// <summary>
        /// 每页数量
        /// </summary>
        [Required]
        public int Size { get; set; }
    }
}
